package com.scs.application.modules.sys.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.query.QueryContextHolder;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.CacheUtils;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UtilCommon;
import com.scs.application.modules.base.util.CommonService;
import com.scs.application.modules.sys.dto.DataViewDTO;
import com.scs.application.modules.sys.entity.DataView;
import com.scs.application.modules.sys.mapper.DataViewMapper;
import com.scs.application.modules.sys.service.DataViewService;
import com.scs.application.modules.sys.service.TableDataViewService;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统文件上传表 服务实现类
 * </p>
 */

@Slf4j
@Service
public class TableDataViewServiceImpl extends BaseServiceImpl<DataViewMapper, DataView> implements TableDataViewService, DataViewService {
    @Override
    public List<DataViewDTO> getDataViewList() {
        List<DataView> dataViews = this.list(Wrappers.<DataView>query().select("view_key,view_name,module_name,description,view_type,columns,creator,gmt_create,modifier,gmt_modified").orderByAsc("view_name"));
        if (dataViews != null && dataViews.size() > 0) {
            List<DataViewDTO> dataViewDTOS = Lists.newArrayListWithCapacity(dataViews.size());
            for(DataView dataView : dataViews) {
                DataViewDTO dataViewDTO = new DataViewDTO();
                dataViewDTO.setViewKey(dataView.getViewKey()).setViewName(dataView.getViewName())
                        .setModuleName(dataView.getModuleName()).setDescription(dataView.getDescription())
                        .setViewType(dataView.getViewType()).setColumns(dataView.getColumns().toJSONString())
                        .setCreator(dataView.getCreator()).setModifier(dataView.getModifier())
                        .setTimeCreated(DateUtils.localDateTimeToString(dataView.getGmtCreate()))
                        .setTimeModified(DateUtils.localDateTimeToString(dataView.getGmtModified()));
                dataViewDTOS.add(dataViewDTO);
            }

            QueryContext queryContext = QueryContextHolder.currentContext();
            String viewKey = (String) queryContext.getParams().get("viewKey");
            List<String> svnLockStatusList = new ArrayList<String>();
            List<String> viewTypeList = new ArrayList<String>();
            if (queryContext.getParams().get("svnLockStatus") instanceof JSONArray) {
                svnLockStatusList = (List<String>) queryContext.getParams().get("svnLockStatus");
            }else {
                String svnLockStatus = UtilCommon.getStr((String) queryContext.getParams().get("svnLockStatus"), "");
                if (StringUtils.isNotBlank(svnLockStatus)) svnLockStatusList.add(svnLockStatus);
            }

            if (queryContext.getParams().get("viewType") instanceof JSONArray) {
                viewTypeList = (List<String>) queryContext.getParams().get("viewType");
            }else {
                String viewType = UtilCommon.getStr((String) queryContext.getParams().get("viewType"), "");
                if (StringUtils.isNotBlank(viewType)) viewTypeList.add(viewType);
            }

            List<String> finalSvnLockStatusList = svnLockStatusList;
            List<String> finalViewTypeList = viewTypeList;
            if (StringUtils.isNotBlank(viewKey)) {
                if (svnLockStatusList.size() > 0 && viewTypeList.size() > 0) {

                    dataViewDTOS = dataViewDTOS.stream().filter(dv -> dv.getViewKey().equalsIgnoreCase(viewKey) && finalSvnLockStatusList.contains(dv.getSvnLockStatus()) && finalViewTypeList.contains(dv.getViewType())).collect(Collectors.toList());
                } else if (svnLockStatusList.size() > 0) {
                    dataViewDTOS = dataViewDTOS.stream().filter(dv -> dv.getViewKey().equalsIgnoreCase(viewKey) && finalSvnLockStatusList.contains(dv.getSvnLockStatus())).collect(Collectors.toList());
                } else if (viewTypeList.size() > 0) {
                    dataViewDTOS = dataViewDTOS.stream().filter(dv -> dv.getViewKey().equalsIgnoreCase(viewKey) && finalViewTypeList.contains(dv.getViewType())).collect(Collectors.toList());
                }
            } else {
                if (svnLockStatusList.size() > 0 && viewTypeList.size() > 0) {
                    dataViewDTOS = dataViewDTOS.stream().filter(dv -> finalSvnLockStatusList.contains(dv.getSvnLockStatus()) && finalViewTypeList.contains(dv.getViewType())).collect(Collectors.toList());
                } else if (svnLockStatusList.size() > 0) {
                    dataViewDTOS = dataViewDTOS.stream().filter(dv -> finalSvnLockStatusList.contains(dv.getSvnLockStatus())).collect(Collectors.toList());
                } else if (viewTypeList.size() > 0) {
                    dataViewDTOS = dataViewDTOS.stream().filter(dv -> finalViewTypeList.contains(dv.getViewType())).collect(Collectors.toList());
                }
            }
            return  dataViewDTOS;
        }
        return null;
    }

    @Override
    public Boolean deleteView(String viewKey) {
        this.remove(Wrappers.<DataView>query().eq("view_key", viewKey));
        CacheUtils.remove(CacheUtils.DATAVIEW_CACHE, viewKey);
        return true;
    }

    @Override
    public JSONObject saveView(JSONObject dataViewJson) {
        String viewKey = dataViewJson.getString("viewKey");
        String editStatus = dataViewJson.getString("editStatus");
        BusinessException.throwErrorIf(StringUtils.isBlank(viewKey), "视图标志不可以为空");
        DataView dataView = getDataViewFromJSON(dataViewJson, viewKey, editStatus);
        if (dataView.isNewRecord()) {
            this.save(dataView);
        } else {
            this.updateById(dataView);
        }
        CacheUtils.remove(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey());
        CacheUtils.put(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey(), dataView.getJsonObject().toJSONString());
        dataViewJson.put("id",dataView.getId());
        return dataViewJson;
    }

    /**
     * 从JSON数据库获取DataView
     *
     * @param jsonObject
     * @return
     */
    private DataView getDataViewFromJSON(JSONObject jsonObject, String viewKey, String editStatus) {
        DataView dataView1 = this.getOne(Wrappers.<DataView>query().eq("view_key", viewKey).select("id,view_key").last("limit 1"));

        if (jsonObject.containsKey("id")) {
            String id = jsonObject.getString("id");
            if (StringUtils.isBlank(id) && dataView1 != null) {
                // 新增的化要检查viewKey的唯一性
                throw new BusinessException("viewKey已经存在，请重新命名！");
            }
        } else {
            if ("addNew".equalsIgnoreCase(editStatus) && dataView1 != null) {
                // 新增的化要检查viewKey的唯一性
                throw new BusinessException("viewKey已经存在，请重新命名！");
            }
        }

        DataView dataView = new DataView();
        dataView.setViewKey(viewKey)
                .setViewName(jsonObject.getString("viewName"))
                .setModuleName(jsonObject.getString("moduleName"))
                .setDescription(jsonObject.getString("description"))
                .setViewType(jsonObject.getString("viewType"))
                .setColumns(jsonObject.getJSONArray("columns"))
                .setJsonObject(jsonObject);
        if (dataView1 != null) {
            dataView.setId(dataView1.getId());
        }
        return dataView;
    }

    @Override
    public String listWithSvnLock() {
        return "";
    }

    @Override
    public String getView(String viewKey) {
        DataView dataView = this.getOne(Wrappers.<DataView>query().eq("view_key", viewKey).last("limit 1"));
        if (dataView != null) {
            return dataView.getJsonObject().toJSONString();
        }
        return null;
    }

    @Override
    public List<String> getDataviewViewKeyList() {
        return this.list().stream().map(DataView::getViewKey).collect(Collectors.toList());
    }

    @Override
    public Boolean isSupport(Boolean flagProject) {
        return flagProject;
    }

    @Override
    @Synchronized
    @Transactional(rollbackFor = Exception.class)
    public String syncDataViewsAll() {
        String msg="同步数据视图";
        QueryWrapper queryWrapperAll = Wrappers.<DataView>query();
        int count  =this.count(queryWrapperAll);
        msg+=" 删除数量："+count;
        this.remove(Wrappers.query());

        CommonService.cacheDataview(null);

        count  =this.count(queryWrapperAll);
        msg+=" 新增数量："+count;
        return msg;
    }
}
